--[[
悬赏任务模块功能函数
--]]

local Lang = require("common.Lang")
local ObjHuman = require("core.ObjHuman")
local Msg = require("core.Msg")
local ExcelTaskConf = require("excel.Task")
local ExcelBountyConf = ExcelTaskConf.Bounty
local TaskDefine = require("task.Define")
local TaskHelp = require("task.TaskHelp")
local TaskAction = require("task.TaskAction")
local TaskHandler = require("task.HandlerL")
local Duanceng = require("task.Duanceng")
local Broadcast = require("broadcast.Broadcast")
local Grid = require("bag.Grid")
local TaskLogic = require("task.TaskLogic")
local TaskCallbacks = require("task.TaskCallbacks")
local ShopHelp = require("shop.ShopHelp")
local ActivityLogicL = require("activity.ActivityLogicL")
local VipDefine = require("vip.VipDefine")
local VipLogic  = require("vip.VipLogic")
local MonthCardLogic = require("vip.MonthCardLogic")
local Log = require("common.Log")
local OfficialLogic = require("official.OfficialLogic")

local RetCanDoTasks = {} 
local BountyCache = nil			-- 悬赏任务列表，按颜色分组，用于随机任务

function checkInTable(e, tb)
	for k, v in pairs(tb) do
		if e == v then
			return true
		end
	end
	return false
end

function checkInBountyCanDoList(human, taskID)
  for i = 0, human.db.bountyCanDoListLen -1 do
      if human.db.bountyCanDoList[i] == taskID then
          return true
      end
  end
end

function getRandomTask(human)
	-- 生成悬赏任务列表
	if not BountyCache then
		BountyCache = {}
		for task_id, task_info in pairs(ExcelBountyConf) do
			local color = task_info.color
			if not BountyCache[color] then
				BountyCache[color] = {}
			end
			local len = #BountyCache[color] + 1
			BountyCache[color][len] = task_id
		end
	end
	
	local now_list = {}
	local _, do_list = getBountyDoCnt(human)
	for color, v in pairs(BountyCache) do
		if not now_list[color] then
			now_list[color] = {}
		end
		for k, task_id in pairs(v) do
			--print("color",color, "k,",k,"task_id:", task_id)
			if ExcelBountyConf[task_id].level_min <= human.db.lv 
			and ExcelBountyConf[task_id].level_max >= human.db.lv then			
				if not checkInBountyCanDoList(human, task_id)  and checkInTable(task_id, do_list) == false then
					local len = #now_list[color] + 1
					now_list[color][len] = task_id					
				end				
			end
		end
	end
	
	-- 权重和
	local BountyWeightSum = 0
	local BountyWeightList = {}
	local BountyColorWeight = TaskDefine.BOUNTY_COLOR_WEIGHT
	for i = 1, #BountyColorWeight do		
		local color_weight = BountyColorWeight[i]
		if not now_list[i] or #now_list[i] < 1 then
			color_weight = 0
		end		
		BountyWeightSum = BountyWeightSum + color_weight		
		if i > 1 then
			BountyWeightList[i] = color_weight + BountyWeightList[i - 1]
		else
			BountyWeightList[i] = color_weight
		end		
	end
	
	-- 随机颜色
	if BountyWeightSum < 1 then
		return 0
	end
	local rand_boundty = math.random(1, BountyWeightSum)
	local rand_color = 0
	for i = 1, #BountyColorWeight do
		if rand_boundty <= BountyWeightList[i] then
			rand_color = i
			break
		end
	end
	if rand_color < 1 then
		return 0
	end
	
	-- 随机任务ID
	local list_cnt = #now_list[rand_color]
	local rand_index = math.random(1, list_cnt)
	if rand_index > 0 then
		return now_list[rand_color][rand_index] 
	end
end


function refreshTask(human, isFree)
	if isFree then
		human.db.bountyRefreshTime = os.time()
	end
	human.db.bountyCanDoListLen = 0
	human.db.bountyLv = human.db.lv
	for i = 1, TaskDefine.BOUNTY_CAN_DO_MAX_CNT do
		human.db.bountyCanDoList[i-1] = getRandomTask(human,not isFree)	
		human.db.bountyCanDoListLen = human.db.bountyCanDoListLen + 1
	end
  Log.write(Log.LOGID_OSS_BOUNTY_REFRESH, human._id, human.account, human.name,human.db.lv, isFree and 0 or 1)
end

function getCanDo(human)
	if human.db.bountyRefreshTime == 0 then
		refreshTask(human, true)
	end
	if human.db.bountyLv == 0 or human.db.lv > human.db.bountyLv then
		refreshTask(human, true)
	end
	local len = 0
	RetCanDoTasks = {}
	for i = human.db.bountyCanDoListLen-1, 0, -1 do
		if not ExcelTaskConf.Bounty[human.db.bountyCanDoList[i]] then
			human.db.bountyCanDoList[i] = human.db.bountyCanDoList[human.db.bountyCanDoListLen-1]
			human.db.bountyCanDoListLen = human.db.bountyCanDoListLen -1
		end
	end
	for i = 0, human.db.bountyCanDoListLen-1 do
			len = len + 1
			RetCanDoTasks[i+1] = human.db.bountyCanDoList[i]
	end	
	return len, RetCanDoTasks
end

function checkIsBounty(task_id)
	if ExcelBountyConf[task_id] then
		return true
	end
end

-- 设置任务节点信息
function setTaskNode(taskNode, taskID, human)
	local taskConfig = ExcelBountyConf[taskID]							-- 任务配置信息
	if not taskConfig then
		assert(nil, taskID)
	end
	-- 任务基础信息
	taskNode.taskID = taskID
	taskNode.taskName = taskConfig.name
	if taskConfig.where ~= "" then
		if not taskConfig.taskName then
			taskConfig.taskName = taskConfig.name .. "【" .. taskConfig.where .. "】"
		end
		taskNode.taskName = taskConfig.taskName
	end
	taskNode.color = taskConfig.color
	taskNode.icon = taskConfig.icon
	
	-- 任务对象
	TaskAction.setTaskObj(taskNode, human, taskID, taskConfig)
	
	-- 任务奖励
	local exp, worldExpAdd = TaskHelp.getRewardExp(taskConfig, human)
	taskNode.rewardExp = exp + worldExpAdd
	taskNode.rewardMoney = TaskHelp.getRewardMoney(taskConfig, human)
	taskNode.rewardZhangong = TaskHelp.getRewardZhangong(taskConfig, human)
	taskNode.rewardWushuang = TaskHelp.getRewardWushuang(taskConfig, human)
	taskNode.rewardWeiwang  = TaskHelp.getRewardWeiwang(taskConfig, human)
	taskNode.rewardRongyu   = TaskHelp.getRewardRongyu(taskConfig, human)
	local itemCount, itemGrids = TaskHelp.getRewardItem(taskID, taskConfig, human)
	taskNode.rewardItems[0] = itemCount
	for i = 1, itemCount do 
		Grid.makeItem(itemGrids[i], taskNode.rewardItems[i], 0, human)
	end 
	
end

function setCanDoList(task_list, human)
	local cnt, can_do_list = getCanDo(human)	
	local len = 0
	for i = 1, cnt do
		if can_do_list[i] then
			len = len + 1
			setTaskNode(task_list[len], can_do_list[i], human)			
		end
	end	
	task_list[0] = len
end



-- 判断
function taskCanAccept(human, taskID, taskConfig)
	if human.db.lv < taskConfig.level_min then
		return TaskDefine.TASK_ACCEPT_FAIL_LEVEL
	end
	
--	if human.db.lv > taskConfig.level_max then
--		return TaskDefine.TASK_ACCEPT_FAIL_LEVEL
--	end
	
	-- 每日可接受次数
	if getCnt(human) >= getMaxCnt(human) then
		return TaskDefine.TASK_ACCEPT_FAIL_ACCEPT_CNT_FULL
	end
	
	-- 当前可接受个数
	local do_cnt = getBountyDoCnt(human)
	if do_cnt >= TaskDefine.BOUNTY_DOING_MAX_CNT then
		return TaskDefine.TASK_ACCEPT_FAIL_DOING_CNT_FULL
	end
	
	-- 判断是否在刷出来的列表中
	
	for i =  0 , human.db.bountyCanDoListLen - 1 do
		if human.db.bountyCanDoList[i] == taskID then
			return TaskDefine.TASK_ACCEPT_OK
		end
	end
	
	return TaskDefine.TASK_ACCEPT_FAIL_TASKID_ERROR	
end

-- 每日接受任务次数
function getCnt(human)
	return human.db.bountyDoCnt
end
function getMaxCnt(human)
    return TaskDefine.BOUNTY_CANDO_EVERYDAY + human.db.bountyAddCnt
end

function addCnt(human)
  if human.db.bountyAddCnt >= VipLogic.getVipTimes(human, VipDefine.VIP_PRIVILEGE_BOUNTYTASK) then
      Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.TASK_ADD_CNT_NOT_VIP)
      return
  end
  if ObjHuman.getYuanbao(human) < TaskDefine.BOUNTY_ADD_CNT_RMB then
      ShopHelp.onNoRMB(human)
      return
  end
  ObjHuman.decYuanbao(human, TaskDefine.BOUNTY_ADD_CNT_RMB, "task_bounty_add")
  human.db.bountyAddCnt = human.db.bountyAddCnt + 1
  sendBountyList(human)  
end

local bountyDoList = {}

-- 当前已接悬赏任务个数
function getBountyDoCnt(human)
	local doingTasksLen, doingTasks = TaskHelp.getDoing(human)
	local cnt = 0
	bountyDoList = {}
	
	for i = 1, doingTasksLen do
		local taskConfig = TaskHelp.getTaskConfig(doingTasks[i]) -- 任务配置信息
		
		if taskConfig and taskConfig.mainType == TaskDefine.TASK_TYPE_1_BOUNTY then
			cnt = cnt + 1
			bountyDoList[cnt] = doingTasks[i]
		end
	end
	
	return cnt, bountyDoList
end

function taskDoAccept(human, taskID)	
	-- 删掉已接受的任务，换一个
	for i = 0, human.db.bountyCanDoListLen -1 do
		if human.db.bountyCanDoList[i] == taskID then
			human.db.bountyCanDoList[i] = getRandomTask(human)	
			break
		end
	end
	
	-- 刷新面板信息
	
	TaskHelp.refreshDoing(human)
	
	sendBountyList(human)
  
	
	Duanceng.onBountyCntChange(human)
end


function taskDoFinish(human, taskID, taskConfig)
  human.db.bountyDoCnt = human.db.bountyDoCnt + 1
  sendBountyList(human)  
  ActivityLogicL.updateActivityValue(human, "bounty_task")
  Log.write(Log.LOGID_OSS_BOUNTY_FINISH, human._id, human.account, human.name,human.db.lv, taskID, taskConfig.color)
  
  TaskCallbacks.taskInteractCB(human, TaskDefine.TASK_INTERACT_BOUNTY_FINISH)
  if taskConfig.color == TaskDefine.BOUNTY_ZI_COLOR then
    TaskCallbacks.taskInteractCB(human, TaskDefine.TASK_INTERACT_ZISE_BOUNTY)  
  elseif taskConfig.color == TaskDefine.BOUNTY_CHENG_COLOR then
    TaskCallbacks.taskInteractCB(human, TaskDefine.TASK_INTERACT_CHENGSE_BOUNTY)
  end
  OfficialLogic.checkOneCondition(human, "bountyTask")
  Duanceng.onBountyCntChange(human)
end

-- 发送悬赏任务列表
function sendBountyList(human)
	local msgRet = Msg.gc.GC_BOUNTY_LIST
	setCanDoList(msgRet.canDoTasks, human)
	if human.db.bountyRefreshTime == 0 then
	   msgRet.refreshLeft = 0
	else
	   msgRet.refreshLeft = TaskDefine.BOUNTY_REFRESH_TIME_LEN - os.time() + human.db.bountyRefreshTime
	end
	msgRet.maxTimes = getMaxCnt(human)
	msgRet.doTimes = getCnt(human)
	msgRet.freeTimes = 0

	msgRet.refreshYuanbao = TaskDefine.BOUNTY_REFESH_NEED_YUANBAO
	local do_cnt, do_list = getBountyDoCnt(human)
	msgRet.doTasksDetail[0] = 0
	for i = 1, do_cnt do
		local taskConfig = TaskHelp.getTaskConfig(do_list[i]) -- 任务配置信息
		if taskConfig then
			msgRet.doTasksDetail[0] = msgRet.doTasksDetail[0] + 1
			msgRet.doTasksDetail[msgRet.doTasksDetail[0]].taskID = do_list[i]
			msgRet.doTasksDetail[msgRet.doTasksDetail[0]].where = taskConfig.where
		end
	end	

	Msg.send(msgRet, human.fd)
end

-- 刷新悬赏任务
function refreshBountyList(human)
	-- 每日任务上限了不让刷~
	if getCnt(human) >= getMaxCnt(human) then
		Broadcast.sendBroadcast(human, Lang.DOWN, Lang.TASK_BOUNTY_REFRESH_FAIL_FINISH)
		return
	end

	-- 每20分钟提供一次免费刷新
	if human.db.bountyRefreshTime + TaskDefine.BOUNTY_REFRESH_TIME_LEN < os.time() then
		refreshTask(human, true)
		sendBountyList(human)
		Broadcast.sendBroadcast(human, Lang.DOWN, Lang.TASK_BOUNTY_REFRESH_OK)
		return
	end

  if ObjHuman.getYuanbao(human) >= TaskDefine.BOUNTY_REFESH_NEED_YUANBAO then
				ObjHuman.decYuanbao(human, TaskDefine.BOUNTY_REFESH_NEED_YUANBAO, "refresh_bounty")
				Broadcast.sendBroadcast(human, Lang.DOWN, string.format(Lang.TASK_BOUNTY_REFRESH_OK_YUANBAO, TaskDefine.BOUNTY_REFESH_NEED_YUANBAO))
  else
			  ShopHelp.onNoRMB(human)
				Broadcast.sendBroadcast(human, Lang.DOWN, Lang.TASK_BOUNTY_REFRESH_FAIL)
				return
	end	
	refreshTask(human)
	sendBountyList(human)	
end


-- 花费仙石立刻完成
function autoComplete(human, taskID)
	local config = TaskHelp.getTaskConfig(taskID)
	if config == nil or (config.mainType ~= TaskDefine.TASK_TYPE_1_BOUNTY and config.mainType ~= TaskDefine.TASK_TYPE_1_FAMILYBOUNTY) then return end
	
	local record = TaskLogic.getTaskRecord(human, taskID) 
	
	if record == nil or record.status ~= TaskDefine.TASK_ACCEPTED then return end
	
	local rmbNeed = TaskDefine.BOUNTY_AUTO_COMPLETE_RMB[config.color]
	if not MonthCardLogic.isHaveSpec(human) and ObjHuman.getYuanbao(human) < rmbNeed then
	    ShopHelp.onNoRMB(human)
			Broadcast.sendBroadcast(human, Lang.DOWN, Lang.TASK_BOUNTY_AUTO_COMPLETE_FAIL_RMB)
      return
	end
	
	record.finishFlag = TaskDefine.TASK_FINISH_FLAG_CAN_FINISH
	local tempMsg = {taskID = taskID}
	TaskHandler.CG_TASK_FINISH(human, tempMsg)
	if not MonthCardLogic.isHaveSpec(human) then
	   ObjHuman.decYuanbao(human, rmbNeed, "complete_bounty")
     Broadcast.sendBroadcast(human, Lang.DOWN, string.format(Lang.TASK_BOUNTY_AUTO_COMPLETE_OK_YUANBAO, rmbNeed))
  else
     Broadcast.sendBroadcast(human, Lang.DOWN, Lang.TASK_BOUNTY_AUTO_COMPLETE_OK)     
  end
  
  sendBountyList(human)
end


function updateDaily(human)
    human.db.bountyDoCnt = 0
    human.db.bountyAddCnt = 0
end



